#include <iostream>
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include "../inc/PointCloud.h"
#include "../inc/LoaderOFF.h"

using namespace std;

int loadOffFile ( char* _fileName, PointCloud* _rslt )
{
	FILE* file;
	char header[5];
	int nbVertex, nbEdges, nbFaces;
	
	cout<<"loading \""<<_fileName<<"\""<<endl;
	
	file = fopen ( _fileName, "r" );
	
	if ( file == NULL )
	{
		cout<<"Erreur lors de l'ouverture du fichier\""<<_fileName<<"\"\n";
		return -1;
	}
	
	if ( fscanf(file,"%s",header) == 0 )
	{
		fclose ( file );
		cout<<"En tête du fichier\""<<_fileName<<"\" non valide\n";
		return -1;
	}
	
	if ( strcmp ( header, "OFF" ) == 0 || strcmp ( header, "off" ) == 0 )
	{
		if ( fscanf(file,"%d",&nbVertex) == EOF )
		{
			cout<<"Erreur lors de la lecture du nombre de vertex  du modele"<<endl;
			fclose ( file );
			return -1;
		}
		
		if ( fscanf(file,"%d",&nbFaces) == EOF )
		{
			cout<<"Erreur lors de la lecture du nombre de faces du modele"<<endl;
			fclose ( file );
			return -1;
		}
		
		if ( fscanf(file,"%d",&nbEdges) == EOF )
		{
			cout<<"Erreur lors de la lecture du nombre d'aretes du modele"<<endl;
			fclose ( file );
			return -1;
		}
		
		for ( int i = 0 ; i < nbVertex ; i++ )
		{
			float x,y,z;
			
			if ( fscanf(file,"%f",&x) == EOF )
			{
				cout<<"Erreur lors de la lecture des sommets du modele"<<endl;
				fclose ( file );
				return -1;
			}
			
			if ( fscanf(file,"%f",&y) == EOF )
			{
				cout<<"Erreur lors de la lecture des sommets du modele"<<endl;
				fclose ( file );
				return -1;
			}
			
			if ( fscanf(file,"%f",&z) == EOF )
			{
				cout<<"Erreur lors de la lecture des sommets du modele"<<endl;
				fclose ( file );
				return -1;
			}
			
			_rslt->add(Point (x,y,z,0,0,0));
		}
	}	
	
	else if ( strcmp ( header, "COFF" ) == 0 || strcmp ( header, "coff" ) == 0 )
	{		
		if ( fscanf(file,"%d",&nbVertex) == EOF )
		{
			cout<<"Erreur lors de la lecture du nombre de vertex  du modele"<<endl;
			fclose ( file );
			return -1;
		}
		
		if ( fscanf(file,"%d",&nbFaces) == EOF )
		{
			cout<<"Erreur lors de la lecture du nombre de faces du modele"<<endl;
			fclose ( file );
			return -1;
		}
		
		if ( fscanf(file,"%d",&nbEdges) == EOF )
		{
			cout<<"Erreur lors de la lecture du nombre d'aretes du modele"<<endl;
			fclose ( file );
			return -1;
		}
		
		cout<<"Ce modele contient "<<nbVertex<<" sommets, "<<nbEdges<<" aretes et "<<nbFaces<<" faces.\n";
		
		for ( int i = 0 ; i < nbVertex ; i++ )
		{
			float x,y,z,r,g,b;
			
			if ( fscanf(file,"%f",&x) == EOF )
			{
				cout<<"Erreur lors de la lecture des sommets du modele"<<endl;
				fclose ( file );
				return -1;
			}
			
			if ( fscanf(file,"%f",&y) == EOF )
			{
				cout<<"Erreur lors de la lecture des sommets du modele"<<endl;
				fclose ( file );
				return -1;
			}
			
			if ( fscanf(file,"%f",&z) == EOF )
			{
				cout<<"Erreur lors de la lecture des sommets du modele"<<endl;
				fclose ( file );
				return -1;
			}
			
			if ( fscanf(file,"%f",&r) == EOF )
			{
				cout<<"Erreur lors de la lecture des sommets du modele"<<endl;
				fclose ( file );
				return -1;
			}
			
			if ( fscanf(file,"%f",&g) == EOF )
			{
				cout<<"Erreur lors de la lecture des sommets du modele"<<endl;
				fclose ( file );
				return -1;
			}
			
			if ( fscanf(file,"%f",&b) == EOF )
			{
				cout<<"Erreur lors de la lecture des sommets du modele"<<endl;
				fclose ( file );
				return -1;
			}
			
			_rslt->add(Point (x,y,z,r,g,b));
		}
	}
	
	else
	{
		fclose ( file );
		cout<<"En tête du fichier\""<<_fileName<<"\" non valide\n";
		return -1;
	}
	
	fclose ( file );
	
	cout<<"Done"<<endl;
	cout<<"Ce modele contient "<<nbVertex<<" sommets"<<endl;
	
	return 0;
}

int loadOffFile ( char* _fileName, PointCloud* _rslt, float _zMin, float _zMax )
{
	FILE* file;
	char header[5];
	int nbVertex, nbEdges, nbFaces;
	
	cout<<"loading \""<<_fileName<<"\""<<endl;
	
	file = fopen ( _fileName, "r" );
	
	if ( file == NULL )
	{
		cout<<"Erreur lors de l'ouverture du fichier\""<<_fileName<<"\"\n";
		return -1;
	}
	
	if ( fscanf(file,"%s",header) == 0 )
	{
		fclose ( file );
		cout<<"En tête du fichier\""<<_fileName<<"\" non valide\n";
		return -1;
	}
	
	if ( strcmp ( header, "OFF" ) == 0 || strcmp ( header, "off" ) == 0 )
	{
		if ( fscanf(file,"%d",&nbVertex) == EOF )
		{
			cout<<"Erreur lors de la lecture du nombre de vertex  du modele"<<endl;
			fclose ( file );
			return -1;
		}
		
		if ( fscanf(file,"%d",&nbFaces) == EOF )
		{
			cout<<"Erreur lors de la lecture du nombre de faces du modele"<<endl;
			fclose ( file );
			return -1;
		}
		
		if ( fscanf(file,"%d",&nbEdges) == EOF )
		{
			cout<<"Erreur lors de la lecture du nombre d'aretes du modele"<<endl;
			fclose ( file );
			return -1;
		}
		
		for ( int i = 0 ; i < nbVertex ; i++ )
		{
			float x,y,z;
			
			if ( fscanf(file,"%f",&x) == EOF )
			{
				cout<<"Erreur lors de la lecture des sommets du modele"<<endl;
				fclose ( file );
				return -1;
			}
			
			if ( fscanf(file,"%f",&y) == EOF )
			{
				cout<<"Erreur lors de la lecture des sommets du modele"<<endl;
				fclose ( file );
				return -1;
			}
			
			if ( fscanf(file,"%f",&z) == EOF )
			{
				cout<<"Erreur lors de la lecture des sommets du modele"<<endl;
				fclose ( file );
				return -1;
			}
			
			if ( z < _zMax && z > _zMin )
				_rslt->add(Point (x,y,z,0,0,0));
		}
	}	
	
	else if ( strcmp ( header, "COFF" ) == 0 || strcmp ( header, "coff" ) == 0 )
	{
		if ( fscanf(file,"%d",&nbVertex) == EOF )
		{
			cout<<"Erreur lors de la lecture du nombre de vertex  du modele"<<endl;
			fclose ( file );
			return -1;
		}
		
		if ( fscanf(file,"%d",&nbFaces) == EOF )
		{
			cout<<"Erreur lors de la lecture du nombre de faces du modele"<<endl;
			fclose ( file );
			return -1;
		}
		
		if ( fscanf(file,"%d",&nbEdges) == EOF )
		{
			cout<<"Erreur lors de la lecture du nombre d'aretes du modele"<<endl;
			fclose ( file );
			return -1;
		}
		
		cout<<"Ce modele contient "<<nbVertex<<" sommets, "<<nbEdges<<" aretes et "<<nbFaces<<" faces.\n";
		
		for ( int i = 0 ; i < nbVertex ; i++ )
		{
			float x,y,z,r,g,b;
			
			if ( fscanf(file,"%f",&x) == EOF )
			{
				cout<<"Erreur lors de la lecture des sommets du modele"<<endl;
				fclose ( file );
				return -1;
			}
			
			if ( fscanf(file,"%f",&y) == EOF )
			{
				cout<<"Erreur lors de la lecture des sommets du modele"<<endl;
				fclose ( file );
				return -1;
			}
			
			if ( fscanf(file,"%f",&z) == EOF )
			{
				cout<<"Erreur lors de la lecture des sommets du modele"<<endl;
				fclose ( file );
				return -1;
			}
			
			if ( fscanf(file,"%f",&r) == EOF )
			{
				cout<<"Erreur lors de la lecture des sommets du modele"<<endl;
				fclose ( file );
				return -1;
			}
			
			if ( fscanf(file,"%f",&g) == EOF )
			{
				cout<<"Erreur lors de la lecture des sommets du modele"<<endl;
				fclose ( file );
				return -1;
			}
			
			if ( fscanf(file,"%f",&b) == EOF )
			{
				cout<<"Erreur lors de la lecture des sommets du modele"<<endl;
				fclose ( file );
				return -1;
			}
			
			if ( z < _zMax && z > _zMin )
				_rslt->add(Point (x,y,z,r,g,b));
		}
	}
	
	else
	{
		fclose ( file );
		cout<<"En tête du fichier\""<<_fileName<<"\" non valide\n";
		return -1;
	}
	
	fclose ( file );
	
	cout<<"Done"<<endl;
	cout<<"Ce modele contient "<<nbVertex<<" sommets"<<endl;
	
	return 0;
}

int loadOffFile ( char* _fileName, PointCloud* _rslt,  float* _xMin, float* _yMin, float* _xMax, float* _yMax )
{
	FILE* file;
	char header[5];
	int nbVertex, nbEdges, nbFaces;
	
	*_xMin = LONG_MAX;
	*_yMin = LONG_MAX;
	*_xMax = LONG_MIN;
	*_yMax = LONG_MIN;
	
	cout<<"loading \""<<_fileName<<"\""<<endl;
	
	file = fopen ( _fileName, "r" );
	
	if ( file == NULL )
	{
		cout<<"Erreur lors de l'ouverture du fichier\""<<_fileName<<"\"\n";
		return -1;
	}
	
	if ( fscanf(file,"%s",header) == 0 )
	{
		fclose ( file );
		cout<<"En tête du fichier\""<<_fileName<<"\" non valide\n";
		return -1;
	}
	
	if ( strcmp ( header, "OFF" ) == 0 || strcmp ( header, "off" ) == 0 )
	{
		if ( fscanf(file,"%d",&nbVertex) == EOF )
		{
			cout<<"Erreur lors de la lecture du nombre de vertex  du modele"<<endl;
			fclose ( file );
			return -1;
		}
		
		if ( fscanf(file,"%d",&nbFaces) == EOF )
		{
			cout<<"Erreur lors de la lecture du nombre de faces du modele"<<endl;
			fclose ( file );
			return -1;
		}
		
		if ( fscanf(file,"%d",&nbEdges) == EOF )
		{
			cout<<"Erreur lors de la lecture du nombre d'aretes du modele"<<endl;
			fclose ( file );
			return -1;
		}
		
		for ( int i = 0 ; i < nbVertex ; i++ )
		{
			float x,y,z;
			
			if ( fscanf(file,"%f",&x) == EOF )
			{
				cout<<"Erreur lors de la lecture des sommets du modele"<<endl;
				fclose ( file );
				return -1;
			}
			
			if ( fscanf(file,"%f",&y) == EOF )
			{
				cout<<"Erreur lors de la lecture des sommets du modele"<<endl;
				fclose ( file );
				return -1;
			}
			
			if ( fscanf(file,"%f",&z) == EOF )
			{
				cout<<"Erreur lors de la lecture des sommets du modele"<<endl;
				fclose ( file );
				return -1;
			}
			
			if ( *_xMin > x )
				*_xMin = x;
			
			if ( *_yMin > y )
				*_yMin = y;
			
			if ( *_xMax < x )
				*_xMax = x;
			
			if ( *_yMax < y )
				*_yMax = y;
			
			_rslt->add(Point (x,y,z,0,0,0));
		}
	}	
	
	else if ( strcmp ( header, "COFF" ) == 0 || strcmp ( header, "coff" ) == 0 )
	{
		if ( fscanf(file,"%d",&nbVertex) == EOF )
		{
			cout<<"Erreur lors de la lecture du nombre de vertex  du modele"<<endl;
			fclose ( file );
			return -1;
		}
		
		if ( fscanf(file,"%d",&nbFaces) == EOF )
		{
			cout<<"Erreur lors de la lecture du nombre de faces du modele"<<endl;
			fclose ( file );
			return -1;
		}
		
		if ( fscanf(file,"%d",&nbEdges) == EOF )
		{
			cout<<"Erreur lors de la lecture du nombre d'aretes du modele"<<endl;
			fclose ( file );
			return -1;
		}
		
		cout<<"Ce modele contient "<<nbVertex<<" sommets, "<<nbEdges<<" aretes et "<<nbFaces<<" faces.\n";
		
		for ( int i = 0 ; i < nbVertex ; i++ )
		{
			float x,y,z,r,g,b;
			
			if ( fscanf(file,"%f",&x) == EOF )
			{
				cout<<"Erreur lors de la lecture des sommets du modele"<<endl;
				fclose ( file );
				return -1;
			}
			
			if ( fscanf(file,"%f",&y) == EOF )
			{
				cout<<"Erreur lors de la lecture des sommets du modele"<<endl;
				fclose ( file );
				return -1;
			}
			
			if ( fscanf(file,"%f",&z) == EOF )
			{
				cout<<"Erreur lors de la lecture des sommets du modele"<<endl;
				fclose ( file );
				return -1;
			}
			
			if ( fscanf(file,"%f",&r) == EOF )
			{
				cout<<"Erreur lors de la lecture des sommets du modele"<<endl;
				fclose ( file );
				return -1;
			}
			
			if ( fscanf(file,"%f",&g) == EOF )
			{
				cout<<"Erreur lors de la lecture des sommets du modele"<<endl;
				fclose ( file );
				return -1;
			}
			
			if ( fscanf(file,"%f",&b) == EOF )
			{
				cout<<"Erreur lors de la lecture des sommets du modele"<<endl;
				fclose ( file );
				return -1;
			}
			
			if ( *_xMin > x )
				*_xMin = x;
			
			if ( *_yMin > y )
				*_yMin = y;
			
			if ( *_xMax < x )
				*_xMax = x;
			
			if ( *_yMax < y )
				*_yMax = y;
			
			_rslt->add(Point (x,y,z,r,g,b));
		}
	}
	
	else
	{
		fclose ( file );
		cout<<"En tête du fichier\""<<_fileName<<"\" non valide\n";
		return -1;
	}
	
	fclose ( file );
	
	cout<<"Done"<<endl;
	cout<<"Ce modele contient "<<nbVertex<<" sommets"<<endl;
	
	return 0;
}

int loadOffFile ( char* _fileName, PointCloud* _rslt,  float* _xMin, float* _yMin, float* _zMin, float* _xMax, float* _yMax, float* _zMax )
{
	FILE* file;
	char header[5];
	int nbVertex, nbEdges, nbFaces;
	
	*_xMin = LONG_MAX;
	*_yMin = LONG_MAX;
	*_zMin = LONG_MAX;
	*_xMax = LONG_MIN;
	*_yMax = LONG_MIN;
	*_zMax = LONG_MIN;
	
	cout<<"loading \""<<_fileName<<"\""<<endl;
	
	file = fopen ( _fileName, "r" );
	
	if ( file == NULL )
	{
		cout<<"Erreur lors de l'ouverture du fichier\""<<_fileName<<"\"\n";
		return -1;
	}
	
	if ( fscanf(file,"%s",header) == 0 )
	{
		fclose ( file );
		cout<<"En tête du fichier\""<<_fileName<<"\" non valide\n";
		return -1;
	}
	
	if ( strcmp ( header, "OFF" ) == 0 || strcmp ( header, "off" ) == 0 )
	{
		if ( fscanf(file,"%d",&nbVertex) == EOF )
		{
			cout<<"Erreur lors de la lecture du nombre de vertex  du modele"<<endl;
			fclose ( file );
			return -1;
		}
		
		if ( fscanf(file,"%d",&nbFaces) == EOF )
		{
			cout<<"Erreur lors de la lecture du nombre de faces du modele"<<endl;
			fclose ( file );
			return -1;
		}
		
		if ( fscanf(file,"%d",&nbEdges) == EOF )
		{
			cout<<"Erreur lors de la lecture du nombre d'aretes du modele"<<endl;
			fclose ( file );
			return -1;
		}
		
		for ( int i = 0 ; i < nbVertex ; i++ )
		{
			float x,y,z;
			
			if ( fscanf(file,"%f",&x) == EOF )
			{
				cout<<"Erreur lors de la lecture des sommets du modele"<<endl;
				fclose ( file );
				return -1;
			}
			
			if ( fscanf(file,"%f",&y) == EOF )
			{
				cout<<"Erreur lors de la lecture des sommets du modele"<<endl;
				fclose ( file );
				return -1;
			}
			
			if ( fscanf(file,"%f",&z) == EOF )
			{
				cout<<"Erreur lors de la lecture des sommets du modele"<<endl;
				fclose ( file );
				return -1;
			}
			
			if ( *_xMin > x )
				*_xMin = x;
			
			if ( *_yMin > y )
				*_yMin = y;
			
			if ( *_zMin > z )
				*_zMin = z;
			
			if ( *_xMax < x )
				*_xMax = x;
			
			if ( *_yMax < y )
				*_yMax = y;
			
			if ( *_zMax < z )
				*_zMax = z;
			
			_rslt->add(Point (x,y,z,0,0,0));
		}
	}	
	
	else if ( strcmp ( header, "COFF" ) == 0 || strcmp ( header, "coff" ) == 0 )
	{		
		if ( fscanf(file,"%d",&nbVertex) == EOF )
		{
			cout<<"Erreur lors de la lecture du nombre de vertex  du modele"<<endl;
			fclose ( file );
			return -1;
		}
		
		if ( fscanf(file,"%d",&nbFaces) == EOF )
		{
			cout<<"Erreur lors de la lecture du nombre de faces du modele"<<endl;
			fclose ( file );
			return -1;
		}
		
		if ( fscanf(file,"%d",&nbEdges) == EOF )
		{
			cout<<"Erreur lors de la lecture du nombre d'aretes du modele"<<endl;
			fclose ( file );
			return -1;
		}
		
		cout<<"Ce modele contient "<<nbVertex<<" sommets, "<<nbEdges<<" aretes et "<<nbFaces<<" faces.\n";
		
		for ( int i = 0 ; i < nbVertex ; i++ )
		{
			float x,y,z,r,g,b;
			
			if ( fscanf(file,"%f",&x) == EOF )
			{
				cout<<"Erreur lors de la lecture des sommets du modele"<<endl;
				fclose ( file );
				return -1;
			}
			
			if ( fscanf(file,"%f",&y) == EOF )
			{
				cout<<"Erreur lors de la lecture des sommets du modele"<<endl;
				fclose ( file );
				return -1;
			}
			
			if ( fscanf(file,"%f",&z) == EOF )
			{
				cout<<"Erreur lors de la lecture des sommets du modele"<<endl;
				fclose ( file );
				return -1;
			}
			
			if ( fscanf(file,"%f",&r) == EOF )
			{
				cout<<"Erreur lors de la lecture des sommets du modele"<<endl;
				fclose ( file );
				return -1;
			}
			
			if ( fscanf(file,"%f",&g) == EOF )
			{
				cout<<"Erreur lors de la lecture des sommets du modele"<<endl;
				fclose ( file );
				return -1;
			}
			
			if ( fscanf(file,"%f",&b) == EOF )
			{
				cout<<"Erreur lors de la lecture des sommets du modele"<<endl;
				fclose ( file );
				return -1;
			}
			
			if ( *_xMin > x )
				*_xMin = x;
			
			if ( *_yMin > y )
				*_yMin = y;
			
			if ( *_zMin > z )
				*_zMin = z;
			
			if ( *_xMax < x )
				*_xMax = x;
			
			if ( *_yMax < y )
				*_yMax = y;
			
			if ( *_zMax < z )
				*_zMax = z;
			
			_rslt->add(Point (x,y,z,r,g,b));
		}
	}
	
	else
	{
		fclose ( file );
		cout<<"En tête du fichier\""<<_fileName<<"\" non valide\n";
		return -1;
	}
	
	fclose ( file );
	
	cout<<"Done"<<endl;
	cout<<"Ce modele contient "<<nbVertex<<" sommets"<<endl;
	
	return 0;
}
